
#ifndef _UNSIGNED_INTEGER_16_H_
#define _UNSIGNED_INTEGER_16_H_

#include "Basic.hpp"

class UnsignedInteger16{
protected:
	UINT16 n;
public:
	
	UINT16 MAX_VALUE = ~0;
	
	CALLCONV UnsignedInteger16(UINT16 i=0){
		n = i;
	}
	
	CALLCONV UnsignedInteger16(char *str, UINT8 radix=10){
		n = 0;
		if(str == (char*)0)
		#ifdef _EXCEPTION_H_
			throw NullPointerException(
				"Attempt to construct an UnsignedInteger16 object with NULL string");
		#else
			return;
		#endif
		else if(radix < 2 || radix > 36)
		#ifdef _EXCEPTION_H_
			throw InvalidArgumentException(
				"Attempt to construct an UnsignedInteger16 object with an invalid radix");
		#else
			return;
		#endif
		else{
			char c;
			for(; (c = *str) != 0; str++){
				if(c >= '0' && c <= '9'){
					c -= '0';
				}else if(c >= 'A' && c <= 'Z'){
					c -= 'A' - 10;
				}else if(c >= 'a' && c <= 'z'){
					c -= 'a' - 10;
				}else{
				#ifdef _EXCEPTION_H_
					throw NumberFormatException();
				#endif
					break;
				}
				if(c >= radix){
				#ifdef _EXCEPTION_H_
					throw NumberFormatException();
				#endif
					break;
				}
				n = n * radix + c;
			}
		}
	}
	
	inline int compareTo(UINT16 i){
		return (n > i) ? 1 : (n < i ? -1 : 0);
	}
	
	inline int compareTo(UnsignedInteger16 ui){
		return compareTo(ui.n);
	}
	
	CALLCONV char* toString(char* buffer, UINT8 radix){
		char temp[8 * sizeof(UINT16)];
		if(this == (UnsignedInteger16*)0)
		#ifdef _EXCEPTION_H_
			throw NullPointerException(
				"Attempt to convert a NULL UnsignedInteger16 to a string");
		#else
			return (char*)0;
		#endif
		if(buffer == (char*)0)
		#ifdef _EXCEPTION_H_
			throw NullPointerException(
				"Attempt to convert a UnsignedInteger16 to a NULL string");
		#else
			return (char*)0;
		#endif
		if(radix < 2 || radix > 36)
		#ifdef _EXCEPTION_H_
			throw InvalidArgumentException(
				"Attempt to convert an UnsignedInteger16 object to a string with an invalid radix");
		#else
			return (char*)0;
		#endif
		
		if(n == 0){
			buffer[0] = '0'; buffer[1] = 0;
			return buffer;
		}
		int i = 0, j = 0;
		unsigned q = n, r;
		while(q != 0){
			r = q % radix;
			q = q / radix;
			temp[i] = r + '0';
			if(temp[i] > '9') temp[i] += 'A'-'9'-1;
			i++;
		}
		do{
			buffer[j++] = temp[i--]
		}while(i > 0);
		return buffer;
	}
	
}; // class UnsignedInteger16
#endif // _UNSIGNED_INTEGER_16_H_
